﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using AGB.Managerial;
using Zeta;
using Zeta.Common;
using Zeta.Internals.Actors;

namespace AGB.Modules.FrontalLobe_.CombatBehavior
{
    public class CombatContext
    {
        private GenericCombat _genericCombat;

        public CombatContext(GenericCombat gc)
        {
            _genericCombat = gc;
        }

        private CerebralCortex _cortex = BotManager.CerebralCortex;
        private readonly UnitManager _unitManager = BotManager.UnitManager;
        private List<CachedUnit> _nearbyTargets = null; 
        private CachedUnit _currentTarget = null;
        private CachedUnit _priorityTarget = null;
        private SNOPower _nextAttack = SNOPower.Interact_Crouching;
        private long _lastReset = 0;
        private long _resetTimeout = 3000;

        //Interact Crouching: null
       
        public const SNOPower NullPower = SNOPower.Interact_Crouching;
        public bool Cluster = false;
        public bool IsActive = false;
        public float CombatRange = 0;
        
        public String PriorityTargetName = "";

        public void Reset()
        {
            
            _currentTarget = null;
            if (_nearbyTargets != null) _nearbyTargets.Clear();
            _nearbyTargets = null;
            _priorityTarget = null;
            Cluster = false;
            
            _nextAttack = SNOPower.Interact_Crouching;
            _lastReset = Environment.TickCount;
        }

        public void Validate()
        {
            if (_priorityTarget != null) if (_priorityTarget.Invalid) Reset();
            if (_currentTarget != null) if (_currentTarget.Invalid) Reset();
            if (_lastReset+_resetTimeout < Environment.TickCount)
            {
                Reset();
            }
        }

        public CachedUnit PriorityTarget
        {
            get
            {
                Validate();
                if (PriorityTargetName.Length < 2) return default(CachedUnit);

                if (_priorityTarget != null) return _priorityTarget;

                _priorityTarget = default(CachedUnit);

                foreach (var nearbyTarget in NearbyTargets)
                {
                    if (nearbyTarget.Name.Contains(PriorityTargetName))
                    {
                        
                        _priorityTarget = nearbyTarget;
                        return _priorityTarget;
                    }
                }
                
                return _priorityTarget;
            }
        }

        public CachedUnit NearestMob
        {
            get
            {
                Validate();
                return _unitManager.GetClosestHostile();
            }
        }

        public CachedUnit CurrentTarget
        {
            get
            {
                Validate();
                if (_currentTarget == null)
                    _currentTarget = PriorityTarget ?? NearestMob;
                return _currentTarget;
            }
            set { _currentTarget = value; }
        }

        public SNOPower NextAttack
        {
            get
            {
                Validate();
                if (_nextAttack == NullPower) _nextAttack = _genericCombat.DefaultAttack;
                return _nextAttack;
            }
            set { _nextAttack = value; }
        }

        public List<CachedUnit> NearbyTargets
        {
            get
            {
                Validate();
                if (_nearbyTargets != null) return _nearbyTargets;
                _nearbyTargets = new List<CachedUnit>();
                var queue = _unitManager.GetHostiles();
                while (queue.Count > 0)
                {
                    
                    var unit = queue.DequeueValue();
                    if (unit.getDistance() < CombatRange) _nearbyTargets.Add(unit);
                }
                return _nearbyTargets;
            }
        } 
    }
}
